﻿using LogSystem;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using com.yoozoo.gta.Extension.UGUI.ScreenOrientationEx;
using UnityEditor;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.Profiling;
using Yoozoo.Core.Extensions.CSharp;
using Yoozoo.Framework.Core;
using Yoozoo.Manager;
using Yoozoo.Managers.ResourceManagerV2.Framework.Resource;
using Yoozoo.Managers.ResourceManagerV2.Runtime;
using Yoozoo.Modules.Entry;
using ResourceDownloadInfo = Yoozoo.Managers.ResourceManagerV2.Framework.Resource.DownloadInfo;

namespace Yoozoo.Modules.Download
{
    /// <summary>
    /// 边玩边下
    /// </summary>
    public class DownloadWhilePlayingManager : SingletonMono<DownloadWhilePlayingManager>
    {
        /// <summary>
        /// 下载任务
        /// </summary>
        public class Task
        {
            public ResourceDownloadInfo ResourceDownloadInfo;
            public DownloadInfo DownloadInfo;
            public int RetryCount;
            public int Priority;
        }

        /// <summary>
        /// 总的下载状态
        /// </summary>
        public enum Status
        {
            /// <summary>
            /// 未定义，如不是边玩边下模式，或者已下载整包
            /// </summary>
            None,

            /// <summary>
            /// 已初始化，等待下载
            /// </summary>
            Initialized,

            /// <summary>
            /// 下载中
            /// </summary>
            Downloading,

            /// <summary>
            /// 下载完成
            /// </summary>
            Finish,

            /// <summary>
            /// 下载失败
            /// </summary>
            Failed,
        }

        /// <summary>
        /// 错误原因，从个性到共性排列，优先显示共性错误原因
        /// </summary>
        public enum Error
        {
            None,

            Unknown,

            /// <summary>
            /// 文件不存在
            /// </summary>
            NotFound,

            /// <summary>
            /// 网络异常
            /// </summary>
            NetworkNotReachable,

            /// <summary>
            /// 磁盘满
            /// </summary>
            DiskFull,
        }

        /// <summary>
        /// 是否确认已下载完成，下载完成后需要弹窗让玩家确认
        /// </summary>
        public bool IsChecked;

        /// <summary>
        /// 错误号
        /// </summary>
        public int ErrorId;

        /// <summary>
        /// 下载状态
        /// </summary>
        private Status downloadStatus;

        /// <summary>
        /// 下载状态
        /// </summary>
        public Status DownloadStatus
        {
            get
            {
                // 由于要重试3次才会判定为失败，但是DownloadManager在NotReachable时不会再发送WebRequest，凑不齐3次失败
                // 所以检查到NotReachable，直接返回失败
                if (downloadStatus == Status.Downloading &&
                    Application.internetReachability == NetworkReachability.NotReachable)
                    return Status.Failed;

                return downloadStatus;
            }
        }

        /// <summary>
        /// 单个文件的重试次数
        /// </summary>
        public int MaxRetryCount = 3;

        ///// <summary>
        ///// 校验资源线程数
        ///// </summary>
        //public int MaxCheckResourceCount = 4;

        /// <summary>
        /// 重试等待时间（秒）
        /// </summary>
        private float[] retryTimes = new[] { 5f, 15f, 30f, 60 };

        /// <summary>
        /// 重试次数
        /// </summary>
        private int retryCount = 0;

        private float retryTimer = 0;

        public static DownloadWhilePlayingManager Instance => GetInstance("DownloadWhilePlaying");

        /// <summary>
        /// 待下载任务
        /// </summary>
        private List<Task> tasks = new List<Task>();

        /// <summary>
        /// 下载结束的任务，待检查
        /// </summary>
        private List<Task> finishTasks = new List<Task>();

        /// <summary>
        /// 校验成功的任务
        /// </summary>
        private List<Task> successTasks = new List<Task>();

        /// <summary>
        /// 失败的任务（下载失败，校验失败等）
        /// </summary>
        private List<Task> failedTasks = new List<Task>();

        //private List<CheckResourceThread> checkResourceThreads = new List<CheckResourceThread>();

        /// <summary>
        /// 总大小，字节数
        /// </summary>
        private int totalSize;

        /// <summary>
        /// 已下载大小，字节数，必须校验通过才计入已下载
        /// </summary>
        private int downloadedSize;

        /// <summary>
        /// 用0~1的数表示下载的进度
        /// </summary>
        /// <returns></returns>
        public float GetProgress()
        {
            if (totalSize == 0)
                return 1;

            return (float) downloadedSize / totalSize;
        }

        /// <summary>
        /// 总大小，字节数
        /// </summary>
        /// <returns></returns>
        public int GetTotalSize()
        {
            return totalSize;
        }

        /// <summary>
        /// 已下载大小，字节数，必须校验通过才计入已下载
        /// </summary>
        /// <returns></returns>
        public int GetDownloadedSize()
        {
            return downloadedSize;
        }

        public void Initialize()
        {
            var downloadInfos = ResourceV2Entry.Resource.GetUpdateInBackgroundResources();
            if (downloadInfos.Count == 0)
            {
                Log.Info("UpdateInBackgroundResources: 0 files");
                return;
            }

            base.Initialize();

            _checkResource = CheckResource;

            if (!DownloadManager.p_IsInitialize)
            {
                var downloadManager = DownloadManager.Instance;
                var grade = DevicesGrading.Instance.DeviceGradeInfo;
                downloadManager.SetLimitByDeviceGrade(grade);
                downloadManager.Initialize();
            }

            LoadPriorityData(downloadInfos, GenerateDownloadTasks);
        }

        private void GenerateDownloadTasks(List<ResourceDownloadInfo> downloadInfos, Dictionary<string, int> map)
        {
            int size = 0;
            for (var i = 0; i < downloadInfos.Count; i++)
            {
                var downloadInfo = downloadInfos[i];
                size += downloadInfo.ZipLength;
                var task = new Task
                {
                    ResourceDownloadInfo = downloadInfo
                };

                if (map != null && map.TryGetValue(downloadInfo.ResourceName.RawName, out int priority))
                {
                    // 先下载优先级列表中的资源
                    task.Priority = priority;
                }
                else if (downloadInfo.ResourceName.RawName.StartsWith("Movie"))
                {
                    // 然后是视频
                    task.Priority = 100000 + i;
                }
                else if (downloadInfo.ResourceName.RawName.StartsWith("Audio"))
                {
                    // 然后是音频
                    task.Priority = 200000 + i;
                }
                else
                {
                    // 最后是普通资源
                    task.Priority = 300000 + i;
                }
                tasks.Add(task);
            }
            
            totalSize = ResourceV2Entry.Resource.GetUnpackedResourceSize();
            downloadedSize = Math.Max(totalSize - size, 0);
            downloadStatus = Status.Initialized;
            IsChecked = false;

            Log.Info("UpdateInBackgroundResources: {0} files, {1} bytes({2} bytes downloaded) / {3} bytes total",
                downloadInfos.Count, totalSize - downloadedSize, downloadedSize, totalSize);
        }

        public static string PriorityDataFileName
        {
            get
            {
                if (Screen.orientation == UnityEngine.ScreenOrientation.LandscapeLeft || Screen.orientation == UnityEngine.ScreenOrientation.LandscapeRight)
                {
                        return "remainingAssets.dat";
                }
                if(Screen.orientation == ScreenOrientation.Portrait || Screen.orientation == ScreenOrientation.PortraitUpsideDown)
                {
                    return "remainingAssets_Portrait.dat";
                }
                return  "remainingAssets.dat";
                
            }
        }

        public static List<string> PriorityDataFileNames()
        {
            return new List<string>(2){"remainingAssets.dat", "remainingAssets_Portrait.dat"};
        }
        /// <summary>
        /// 读取文件，优先从persistentDataPath读取，没有的话从streamingAssetsPath下读取
        /// </summary>
        /// <param name="fileName"></param>
        /// <param name="onSuccess"></param>
        /// <param name="onFailed"></param>
        /// <returns></returns>
        public static IEnumerator ReadPriorityFile(string fileName, Action<byte[]> onSuccess, Action onFailed)
        {
            // 先从远端读取
            string remotePath = $"{Application.persistentDataPath}/{fileName}";
            if (File.Exists(remotePath))
            {
                var buffer = File.ReadAllBytes(remotePath);
                //Debug.Log($"Read file from {remotePath}, size = {buffer.Length}");
                onSuccess?.Invoke(buffer);
                yield break;
            }

            // 从本地读取
            string localPath = $"{Application.streamingAssetsPath}/{fileName}";
            if (!localPath.Contains("://"))
                localPath = "file://" + localPath;

            //Debug.Log($"Request file from {localPath}");
            var www = UnityWebRequest.Get(localPath);
            yield return www.SendWebRequest();

            if (www.result == UnityWebRequest.Result.Success)
            {
                var buffer = www.downloadHandler.data;
                //Debug.Log($"Read file from {localPath}, size = {buffer.Length}");
                onSuccess?.Invoke(buffer);
            }
            else
            {
                // 读取失败
                Debug.LogError(www.error);
                onFailed?.Invoke();
            }
        }

        private void LoadPriorityData(List<ResourceDownloadInfo> downloadInfos, Action<List<ResourceDownloadInfo>, Dictionary<string, int>> callback)
        { 
            StartCoroutine(ReadPriorityFile(PriorityDataFileName, OnReadVersionSuccess, OnReadVersionFailed));
            
            void OnReadVersionFailed()
            {
                Debug.LogWarning("Read remainingAssets.dat failed");
                callback?.Invoke(downloadInfos, null);
            }

            void OnReadVersionSuccess(byte[] buffer)
            {
                if (buffer == null || buffer.Length == 0)
                {
                    callback?.Invoke(downloadInfos, null);
                    return;
                }

                var map = new Dictionary<string, int>();
                int priority = 0;
                using (var memoryStream = new MemoryStream(buffer))
                using (var streamReader = new StreamReader(memoryStream))
                {
                    while (!streamReader.EndOfStream)
                    {
                        string line = streamReader.ReadLine();
                        if (string.IsNullOrEmpty(line))
                            continue;
                        string resourceName = line.Trim();
                        if (!map.ContainsKey(resourceName))
                        {
                            priority++;
                            map[resourceName] = priority;
                        }
                    }
                }

                callback?.Invoke(downloadInfos, map);
            }
        }

        public void Clear()
        {
            if (DownloadStatus == Status.Finish)
            {
                tasks.Clear();
                finishTasks.Clear();
                failedTasks.Clear();
                successTasks.Clear();

                downloadStatus = Status.None;

                // 销毁DownloadManager
                if (DownloadManager.p_IsInitialize && DownloadManager.Instance.IsIdle())
                    DownloadManager.Instance.Dispose();
            }
        }


        /// <summary>
        /// 有文件下载结束（成功或者失败），更新下载状态
        /// </summary>
        private void UpdateStatus()
        {
            // 任意下载任务失败，状态改为失败。但是其他下载还在继续
            if (failedTasks.Count > 0)
            {
                downloadStatus = Status.Failed;
                return;
            }

            // 无待下载，待校验任务，结束
            if (tasks.Count == 0 && finishTasks.Count == 0)
            {
                downloadStatus = Status.Finish;
            }
        }

        /// <summary>
        /// 玩家点击重试，重置自动重试次数
        /// </summary>
        public void ManuelRetry()
        {
            if (downloadStatus != Status.Failed)
                return;

            if (!DownloadManager.Instance.IsActive())
                DownloadManager.Instance.Resume();
            retryTimer = 0;
            retryCount = 0;
            RetryAll();
        }

        /// <summary>
        /// 全部重试
        /// </summary>
        private void RetryAll()
        {
            if (downloadStatus != Status.Failed)
                return;

            downloadStatus = Status.Downloading;
            ErrorId = 0;

            // 重置失败任务的重试次数，重新下载
            foreach (var failedTask in failedTasks)
            {
                failedTask.RetryCount = 0;
                tasks.Add(failedTask);
                StartOne(failedTask);
            }
            failedTasks.Clear();
        }

        /// <summary>
        /// 重试单个下载任务
        /// </summary>
        /// <param name="task"></param>
        private void Retry(Task task)
        {
            var resourceDownloadInfo = task.ResourceDownloadInfo;
            if (task.RetryCount >= MaxRetryCount)
            {
                // 重试次数达到上限，移动到失败列表中，更新状态
                UnityEngine.Debug.LogFormat("Retry failed: {0} -> {1}, Retry: {2}", resourceDownloadInfo.Url, resourceDownloadInfo.Path, task.RetryCount);
                failedTasks.Add(task);
                tasks.Remove(task);

                UpdateErrorId(task.DownloadInfo.ErrorMessage);
                UpdateStatus();
                return;
            }

            // 重新下载
            task.RetryCount++;
            singleFileRetryCount++;
            //UnityEngine.Debug.LogFormat("Retry: {0} -> {1}, Retry: {2}", resourceDownloadInfo.Url, resourceDownloadInfo.Path, task.RetryCount);
            task.DownloadInfo = StartOne(task);
        }

        /// <summary>
        /// 检查失败原因
        /// </summary>
        /// <param name="errorMessage"></param>
        private void UpdateErrorId(string errorMessage)
        {
            int errorId = 0;

            if (string.IsNullOrEmpty(errorMessage))
            {
                errorId = (int) Error.Unknown;
            }
            else
            {
                // 断网
                // Failed to receive data
                // Cannot connect to destination host

                // 验证没通过, 如需要登录的Wifi连接
                // SSL CA certificate error

                // 一般的超时，或者Wifi连接不上（如开热点的设备关闭网络）
                // Request timeout

                // 磁盘满
                // IOException: Disk full. Path your-local-file-path

                if (errorMessage.Contains("Disk full"))
                {
                    errorId = (int)Error.DiskFull;

                    // 磁盘满立即中断下载
                    DownloadManager.Instance.Pause();
                }
                else if (errorMessage.Contains("Not Found"))
                {
                    errorId = (int) Error.NotFound;
                }
                else if (errorMessage.Contains("Failed to receive data"))
                {
                    errorId = (int)Error.NetworkNotReachable;
                }
                else if (errorMessage.Contains("Cannot connect to destination host"))
                {
                    errorId = (int)Error.NetworkNotReachable;
                }
                else if (errorMessage.Contains("SSL CA certificate error"))
                {
                    errorId = (int)Error.NetworkNotReachable;
                }
                else if (errorMessage.Contains("Request timeout"))
                {
                    errorId = (int)Error.NetworkNotReachable;
                }
            }

            // 各个文件有各个文件的下载失败的原因，通用的原因优先级调高，如网络问题，空间不足，权限不足等等
            // 个别问题优先级降低，如文件不存在，校验出错等
            if (errorId > ErrorId)
            {
                ErrorId = errorId;
            }
        }

        /// <summary>
        /// 开始下载
        /// </summary>
        public void StartAll()
        {
            if (downloadStatus != Status.Initialized)
            {
                return;
            }
            
            downloadStatus = Status.Downloading;
            foreach (var task in tasks)
            {
                task.DownloadInfo = StartOne(task);
            }
        }

        /// <summary>
        /// 开始单个文件的下载
        /// </summary>
        /// <param name="task"></param>
        /// <returns></returns>
        private DownloadInfo StartOne(Task task)
        {
            if (!DownloadManager.p_IsInitialize)
            {
                Debug.LogErrorFormat(LogModule._Default_, "DownloadManager is not initialized!");
            }

            var resourceDownloadInfo = task.ResourceDownloadInfo;
            int priority = task.Priority;

            var url = resourceDownloadInfo.Url;
            // 本地下载路径添加download后缀，检查成功后再改名
            var path = resourceDownloadInfo.Path + ".dp";
            var length = (ulong)resourceDownloadInfo.ZipLength;

            return DownloadManager.Instance.StartDownload(url, path, length, priority,
                (isSuccess) =>
                {
                    OnDownloadFinish(isSuccess, task);
                });
        }

        /// <summary>
        /// 校验成功
        /// </summary>
        /// <param name="task"></param>
        /// <param name="resourceDownloadInfo"></param>
        private void OnCheckSuccess(Task task, ResourceDownloadInfo resourceDownloadInfo)
        {
            Profiler.BeginSample("OnCheckSuccess");
            // 标记资源下载成功
            ResourceV2Entry.Resource.MarkResourceReady(resourceDownloadInfo.ResourceName);
            // 下载字节数增加
            downloadedSize += resourceDownloadInfo.ZipLength;
            // 移动到成功任务中
            successTasks.Add(task);
            // 更新下载状态
            UpdateStatus();
            
            Profiler.EndSample();
            
            // 应该放置的本地资源文件路径
            string path = resourceDownloadInfo.Path;

            if (path.Contains(".bnk"))
            {
                // 下载完音频包，现在不在主线程里，记录一下，以后加载
                string bankName = Path.GetFileNameWithoutExtension(path);
                Debug.LogFormat(LogModule._Default_, "[Audio]OnCheckSuccess: {0} {1}", bankName, path);

                if (bankName == "Music" || bankName == "Voice")
                {
                    lock (bankNameList)
                    {
                        bankNameList.Add(bankName);
                    }
                }
            }
        }

        private void OnDownloadFinish(bool isSuccess, object userData)
        {
            var task = userData as Task;
            if (task == null)
                return;

            var resourceDownloadInfo = task.ResourceDownloadInfo;
            // 远端资源文件的Url
            string url = resourceDownloadInfo.Url;
            // 应该放置的本地资源文件路径
            string path = resourceDownloadInfo.Path;
            // 临时放置的下载文件路径
            string downloadPath = task.DownloadInfo.Path;

            // 可能会提前访问该资源，已经下载完成，这里直接结束 （这不是正常流程，需要避免）
            if (ResourceV2Entry.Resource.IsResourceReady(resourceDownloadInfo.ResourceName))
            {
                Profiler.BeginSample("ResourceReady");
                if (File.Exists(downloadPath))
                    File.Delete(downloadPath);
                    
                // 从待下载任务中移除
                tasks.Remove(task);
                OnCheckSuccess(task, resourceDownloadInfo);
                Profiler.EndSample();
                return;
            }

            //UnityEngine.Debug.LogFormat("Download: {0} -> {1}, {2}", downloadInfo.Url, downloadInfo.Path, isSuccess);
            if (isSuccess)
            {
                Profiler.BeginSample("SuccessTask");
                finishTasks.Add(task);
                Profiler.BeginSample("RemoveSuccessTask");
                tasks.Remove(task);
                Profiler.EndSample();
                OnSuccess(task);
                Profiler.EndSample();
            }
            else
            {
                Profiler.BeginSample("RetryFailedTask");
                // 这里是其他异常，可能是断网，不删除文件，等下次断点续传
                UnityEngine.Debug.LogFormat("Download failed: {0} -> {1}, {2}", url, path, task.DownloadInfo.ErrorMessage);
                Retry(task);
                Profiler.EndSample();
            }
        }

        private void OnSuccess(Task task)
        {

        }

        private void Update()
        {
            if (DownloadStatus == Status.None)
                return;

            Profiler.BeginSample("AutoRetry");
            AutoRetry();
            Profiler.EndSample();

            Profiler.BeginSample("TryCheckResource");
            TryCheckResource();
            Profiler.EndSample();

            lock (bankNameList)
            {
                if (bankNameList.Count > 0)
                {
                    foreach (var bankName in bankNameList)
                    {
                        AudioStudio.AudioManager.LoadBank(bankName);
                    }

                    bankNameList.Clear();
                }
            }

            // 尝试统计边玩边下进度
            Profiler.BeginSample("ClientReportDownloadWhilePlaying");
            EventTracingManager.GetInstance().ClientReportDownloadWhilePlaying(GetProgress());
            Profiler.EndSample();
#if UWA
            UWAEngine.LogValue("DownloadProgress", GetProgress());
#endif
            
        }

        /// <summary>
        /// 自动重试
        /// </summary>
        private void AutoRetry()
        {
            // 如果下载失败，自动等待5，15，30秒自动进行重试
            if (DownloadStatus != Status.Failed)
                return;

            if (Application.internetReachability == NetworkReachability.NotReachable)
                return;

            if (ErrorId == (int)Error.DiskFull)
                return;

            if (retryTimer > 0)
            {
                retryTimer -= Time.deltaTime;
                if (retryTimer < 0)
                {
                    RetryAll();
                }
            }
            else
            {
                //if (retryCount >= retryTimes.Length)
                //    return;

                int index = Math.Min(retryCount, retryTimes.Length - 1);
                retryTimer = retryTimes[index];
                retryCount++;
            }
        }

        private void TryCheckResource()
        {
            if (finishTasks.Count == 0)
                return;

            if (checkResourceThread.State == CheckResourceThread.StateType.Running)
                return;

            checkResourceThread.Start(_checkResource);
        }

        private CheckResourceThread checkResourceThread = new CheckResourceThread();

        private List<string> bankNameList = new List<string>();

        private void CheckResource()
        {
            lock (finishTasks)
            {
                Task task = finishTasks[0];

                var resourceDownloadInfo = task.ResourceDownloadInfo;
                // 远端资源文件的Url
                string url = resourceDownloadInfo.Url;
                // 应该放置的本地资源文件路径
                string targetPath = resourceDownloadInfo.Path;
                // 临时放置的下载文件路径
                string downloadPath = task.DownloadInfo.Path;

                try
                {
                    resourceDownloadInfo.Path = downloadPath;
                    if (ResourceV2Entry.Resource.CheckDownloadFile(resourceDownloadInfo))
                    {
                        if (File.Exists(targetPath))
                        {
                            // 如果目标文件已存在，不会是老版本的文件（老版本文件会走强更，不会走边玩边下）
                            // 那么保留该文件，避免删除时正好要打开该文件，把下载的文件删除
                            File.Delete(downloadPath);
                        }
                        else
                        {
                            // 把下载的文件移动过去
                            File.Move(downloadPath, targetPath);
                        }

                        finishTasks.Remove(task);
                        resourceDownloadInfo.Path = targetPath;
                        OnCheckSuccess(task, resourceDownloadInfo);
                    }
                    else
                    {
                        // 这里CRC校验失败，直接删除文件，重新下载
                        if (File.Exists(downloadPath))
                            File.Delete(downloadPath);

                        resourceDownloadInfo.Path = targetPath;
                        UnityEngine.Debug.LogFormat("Download success but unzip failed: {0} -> {1}", url, targetPath);

                        finishTasks.Remove(task);
                        tasks.Add(task);
                        Retry(task);
                    }
                }
                catch (Exception e)
                {
                    UnityEngine.Debug.LogFormat("Download success but check failed: {0} -> {1}", url, targetPath);
                    UnityEngine.Debug.LogException(e);

                    if (File.Exists(downloadPath))
                        File.Delete(downloadPath);

                    resourceDownloadInfo.Path = targetPath;

                    finishTasks.Remove(task);
                    tasks.Add(task);
                    Retry(task);
                }
            }
        }

        /// <summary>
        /// 下载速度（字节/秒)
        /// </summary>
        public float GetSpeed()
        {
            if (!DownloadManager.p_IsInitialize)
                return 0;
            
            return DownloadManager.Instance.Speed;
        }

        private int singleFileRetryCount = 0;
        private Action _checkResource;
#if DOWNLOAD_WHILE_PLAYING_DEBUG
        
        #region Debug

        // 以下调试功能，待删除
        public int fontSize = 30;


        void OnGUI()
        {
            GUIStyle localStyle = new GUIStyle(GUI.skin.label);
            localStyle.normal.textColor = Color.red;
            localStyle.fontSize = fontSize;

            var rect = new Rect(50, 300, 1200, 100);
            GUI.Label(rect, $"===== Download while playing =====", localStyle);
            rect.y += 30;
            GUI.Label(rect, $"Waiting: {tasks.Count} Downloaded: {finishTasks.Count} Checked: {successTasks.Count} Failed: {failedTasks.Count}", localStyle);
            rect.y += 30;
            GUI.Label(rect, $"RetryAll: {retryCount} Timer: {retryTimer:f2} RetryOne: {singleFileRetryCount}", localStyle);
            rect.y += 30;
            GUI.Label(rect, $"Status: {DownloadStatus}", localStyle);
        }

        #endregion
        
#endif

        public void CreateLargeFile(int size)
        {
            int i = 0;
            string path = $"{Application.persistentDataPath}/largeFile{i}.dat";
            while (File.Exists(path))
            {
                i++;
                path = $"{Application.persistentDataPath}/largeFile{i}.dat";
            }

            // 默认创建1G
            if (size <= 0)
                size = 1024;

            // 写入1mb
            var buffer = new byte[1024 * 1024];

            try
            {
                using (var binaryWriter = new BinaryWriter(File.Open(path, FileMode.Create)))
                {
                    for (int j = 0; j < size; j++)
                    {
                        binaryWriter.Write(buffer);
                        binaryWriter.Flush();
                    }
                }
            }
            catch (Exception e)
            {
                Debug.LogException(e);
            }
        }
    }
}
